#include "../../WizInnerThread.hpp"
#include "../../../../Include/System/WizCallOnce.hpp"

namespace Wiz
{
    namespace Inner
    {
        namespace Thread
        {
            namespace TLS
            {
                ::Wiz::CallOnce::Flag::Type g_TLSInitCallOnceFlag = ::Wiz::CallOnce::Flag::Init;
                DWORD                       g_ThreadTLSKey        = 0;

                ::Wiz::Void::Type CreateCurrentThreadTLSKey()
                {
                    if (g_ThreadTLSKey == 0)
                    {
                        g_ThreadTLSKey = TlsAlloc();
                        if (g_ThreadTLSKey == TLS_OUT_OF_INDEXES)
                        {
                            g_ThreadTLSKey = 0;
                        }
                    }
                }
                ::Wiz::Void::Type CleanUpTLSKey()
                {
                    if (g_ThreadTLSKey != 0)
                    {
                        TlsFree(g_ThreadTLSKey);
                        g_ThreadTLSKey = 0;
                    }
                }
                ::Wiz::Thread::Runnable::Ptr GetCurrentRunnablePtr()
                {
                    if (g_ThreadTLSKey == 0)
                    {
                        return WIZ_NULLPTR;
                    }
                    return ::Wiz::Cast::Static<::Wiz::Thread::Runnable::Ptr>(TlsGetValue(g_ThreadTLSKey));
                }
                ::Wiz::Void::Type SetCurrentRunnablePtr(::Wiz::Void::Ptr RunnableData)
                {
                    ::Wiz::CallOnce::Do(g_TLSInitCallOnceFlag, ::Wiz::Inner::Thread::TLS::CreateCurrentThreadTLSKey);
                    TlsSetValue(g_ThreadTLSKey, RunnableData);
                }
            } /// end of namespace TLS
        } /// end of namespace Thread
    } /// end of namespace Inner
} /// end of namespace Wiz
